package hou.river;

import hou.river.dao.RiverDao;
import hou.river.dao.impl.RiverDaoImpl;
import hou.river.model.DepthData;
import hou.river.util.ConnectionFactory;
import hou.river.util.Matrix;

import java.sql.Connection;
import java.sql.SQLException;

/**
 * @author houweitao 2015年7月2日 上午9:49:37
 */

public class Test {
	static double astar1 = 0;
	static double astar2 = 0;
	static double depth[] = new double[12];
	static DepthData dd = new DepthData();
	public static void main(String[] args) throws SQLException {
		Connection conn = ConnectionFactory.getInstance().makeConnection();
		RiverDao rd = new RiverDaoImpl();

		double yn[] = new double[11];
//		DepthData dd = new DepthData();

		//设置待测的地点
		dd.setX(597129);
		dd.setY(3365496);
		depth = rd.getDepth(conn, dd);//计算出该点12次测量的水深数据，每次测量间隔一周
		for (int i = 0; i < 12; i++)
			System.out.println(depth[i]);

		//进行会度预测
		double[] cgs = buildCumulativeGeneratingSequence(depth); //根据12次水深数据求出累加序列
		System.out.println("累加序列：");
		for (int i = 0; i < 11; i++)
			System.out.println(cgs[i]);

		double[][] b = bulidB(cgs); //根据累加序列求出数据矩阵B的数组

		for (int i = 0; i < 11; i++) {
			yn[i] = depth[i + 1];
			System.out.println("yn" + i + "=" + yn[i]); //数据矩阵yn
		}

		// Matrix matrix = new Matrix(4, 4);
		// matrix.New();
		Matrix matrix = new Matrix(b); //数据矩阵B
		System.out.println("矩阵B");
		matrix.Output();

		
		//计算a撇
		Matrix tran = matrix.Trans();
		System.out.println("矩阵B的转置");
		tran.Output();

		Matrix result = tran.Multiply(matrix).Invs().Multiply(tran);
		System.out.println("矩阵B的转置 乘 矩阵B，的逆矩阵，再乘以矩阵B的转置");
		result.Output();

		for (int i = 0; i < 11; i++) {
			astar1 = astar1 + result.mat[0][i] * yn[i];
			astar2 = astar2 + result.mat[1][i] * yn[i];
		}

		System.out.println("astar1 = "+astar1);
		System.out.println("astar2 = "+astar2);

		// depth[0];

		int k = 20; //这里时间是2013.7.14 + 20周
		outDeep(k);
	}

	//根据给定的时间输出指定位置的水深。
	private static void outDeep(int k) {
		double r = (depth[0] - (astar2 / astar1))
				* Math.pow(Math.E, astar1 * -k) + astar2 / astar1;
		double r2 = (depth[0] - (astar2 / astar1))
				* Math.pow(Math.E, astar1 * -(k - 1)) + astar2 / astar1;
		double tmp = r-r2;
		System.out.println("坐标为("+dd.getX()+","+dd.getY()+");时间为2013/7/13之后第"+k+"周；水深是"+tmp+"米");
	}

	private static double[][] bulidB(double[] cgs) {
		double[][] tmp = new double[11][2];
		for (int i = 0; i < 11; i++) {
			tmp[i][0] = (cgs[i] + cgs[i + 1]) * (-0.5);
			tmp[i][1] = 1;
		}

		return tmp;
	}

	private static double[] buildCumulativeGeneratingSequence(double[] depth) {
		double[] cgs = new double[12];
		for (int i = 0; i < 12; i++)
			cgs[i] = 0;

		for (int i = 0; i < 12; i++) {
			for (int j = 0; j <= i; j++)
				cgs[i] = cgs[i] + depth[j];
		}

		return cgs;
	}
}
